package ctrconfig

import (
	"cloud_worm/util/umodels/mysqldb"
	"cloud_worm/util/umodels/mysqldb/dbmanager"
	"fmt"
	"cloud_worm/util/uhttp"
	"github.com/astaxie/beego/logs"
	"io/ioutil"
	"encoding/json"
	"time"
	"cloud_worm/util/uid"
)

type AdminController struct {
	LoginCtr
}

func (c *AdminController) All()  {
	c.Admin()

	offset, limit := c.DealPage()
	status, err := c.GetInt("status", mysqldb.StatusAll)
	role, err := c.GetInt("role", mysqldb.SelectIntAll)
	username := c.GetString("username")

	webUser := &dbmanager.WebUser{}
	count, err := webUser.Count(status, username, role, mysqldb.SelectIntAll, mysqldb.SelectIntAll)
	if err != nil {
		logs.Warn(fmt.Sprintf("error in get count: %s.", err.Error()))
		data := map[string]interface{}{"total": 0, "data": []dbmanager.WebUser{}}
		c.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr, "get count error.", data)
		c.ServeJSON()
		return
	}
	if count == 0 {
		data := map[string]interface{}{"total": count, "data": []dbmanager.WebUser{}}
		c.Data["json"] = uhttp.CreateOkResponse(data)
		c.ServeJSON()
		return
	}

	users, err := webUser.Select(offset, limit, status, username, role, mysqldb.SelectIntAll, mysqldb.SelectIntAll)
	if err != nil {
		logs.Warn(fmt.Sprintf("select webuser error: %s", err.Error()))
		data := map[string]interface{}{"total": 0, "data": []dbmanager.WebUser{}}
		c.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr, "select error.", data)
		c.ServeJSON()
		return
	}

	data := map[string]interface{}{"total": count, "data": users}
	c.Data["json"] = uhttp.CreateOkResponse(data)
	c.ServeJSON()
	return
}

func (c *AdminController) Set()  {
	c.Admin()

	type UserInfo struct {
		Id 			int64
		Role 		int
		Status 		int
	}
	body, err := ioutil.ReadAll(c.Ctx.Request.Body)
	if err != nil {
		c.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeReqBodyErr, err.Error(), nil)
		c.ServeJSON()
		return
	}
	var input UserInfo
	if err = json.Unmarshal(body, &input); err != nil {
		c.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeReqBodyErr, "input Unmarshal error.", nil)
		c.ServeJSON()
		return
	}

	if input.Role != dbmanager.RoleAdmin && input.Role != dbmanager.RoleManager && input.Role != dbmanager.RoleGuest {
		c.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeReqBodyErr, "input role error.", nil)
		c.ServeJSON()
		return
	}
	if c.UserInfo.Id == input.Id && input.Status != mysqldb.StatusValid {		// 不允许把自己设置为无效
		c.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeReqBodyErr, "can't set self to invalid.", nil)
		c.ServeJSON()
		return
	}

	webUser := &dbmanager.WebUser{Id: input.Id}
	if err := webUser.Read("id"); err != nil {
		logs.Warn(fmt.Sprintf("edit input id error: %s.", err.Error()))
		c.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr, "input id error.", nil)
		c.ServeJSON()
		return
	}
	webUser.Role = input.Role
	webUser.Status = input.Status
	webUser.Updated = time.Now().Unix()
	if err := webUser.Update("status", "role", "updated"); err != nil {
		logs.Warn(fmt.Sprintf("updated error: %s.", err.Error()))
		c.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr, "updated error.", nil)
		c.ServeJSON()
		return
	}

	c.Data["json"] = uhttp.CreateOkResponse(nil)
	c.ServeJSON()
	return
}

func (c *AdminController) Add() {
	c.Admin()

	type UserInfo struct {
		Username 		string
		Password 		string
		Role 			int
	}
	body, err := ioutil.ReadAll(c.Ctx.Request.Body)
	if err != nil {
		c.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeReqBodyErr, err.Error(), nil)
		c.ServeJSON()
		return
	}
	var input UserInfo
	if err = json.Unmarshal(body, &input); err != nil {
		c.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeReqBodyErr, "input Unmarshal error.", nil)
		c.ServeJSON()
		return
	}
	if input.Username == mysqldb.SelectStrAll || input.Password == mysqldb.SelectStrAll || input.Role == dbmanager.RoleAdmin {
		c.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr, "input param error.", nil)
		c.ServeJSON()
		return
	}
	// todo：密码合规性检查

	webUser := &dbmanager.WebUser{Username: input.Username}
	if err := webUser.Read("username"); err == nil {
		c.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr, "input username had, can't add.", nil)
		c.ServeJSON()
		return
	}
	passwd, err := uid.PasswordHash(input.Password)
	if err != nil {
		c.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr, "input param err.", nil)
		c.ServeJSON()
		return
	}
	webUser.Password = passwd
	webUser.Role = input.Role
	webUser.Created = time.Now().Unix()
	webUser.Updated = webUser.Created
	webUser.Status = mysqldb.StatusValid
	if err := webUser.Insert(); err != nil {
		c.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr, "input param err.", nil)
		c.ServeJSON()
		return
	}
	// todo：通知目标人

	c.Data["json"] = uhttp.CreateOkResponse(nil)
	c.ServeJSON()
	return
}